/* Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
 * Description: Module signature cert and crl buffer.
 * Author: wanglei
 * Create: 2020-09-24
 */

#include <linux/slab.h>
#include <linux/export.h>
#include <linux/crl_revocate.h>

unsigned char *crl_cert;
unsigned long crl_cert_size;

#ifdef CONFIG_RTOS_EXTRA_CERTIFICATE
unsigned char *crl_cert_second;
unsigned long crl_cert_size_second;
#endif

crl_bundle_buffer crl_bundle_ondevice;

unsigned char *get_crl_cert(void)
{
	return crl_cert;
}
#ifdef CONFIG_EULEROS_CMS_CBB
EXPORT_SYMBOL_GPL(get_crl_cert);
#else
EXPORT_SYMBOL_NS(get_crl_cert, HW_RTOS_NS);
#endif

unsigned long get_crl_cert_size(void)
{
	return crl_cert_size;
}
#ifdef CONFIG_EULEROS_CMS_CBB
EXPORT_SYMBOL_GPL(get_crl_cert_size);
#else
EXPORT_SYMBOL_NS(get_crl_cert_size, HW_RTOS_NS);
#endif

#ifdef CONFIG_RTOS_EXTRA_CERTIFICATE
unsigned char *get_crl_cert_second(void)
{
	return crl_cert_second;
}
EXPORT_SYMBOL_NS(get_crl_cert_second, HW_RTOS_NS);

unsigned long get_crl_cert_size_second(void)
{
	return crl_cert_size_second;
}
EXPORT_SYMBOL_NS(get_crl_cert_size_second, HW_RTOS_NS);
#endif

size_t get_crl_ondevice_size(void)
{
	return crl_bundle_ondevice.size;
}
#ifdef CONFIG_EULEROS_CMS_CBB
EXPORT_SYMBOL_GPL(get_crl_ondevice_size);
#else
EXPORT_SYMBOL_NS(get_crl_ondevice_size, HW_RTOS_NS);
#endif

void set_crl_ondevice_size(size_t size)
{
	crl_bundle_ondevice.size = size;
	return;
}
#ifdef CONFIG_EULEROS_CMS_CBB
EXPORT_SYMBOL_GPL(set_crl_ondevice_size);
#else
EXPORT_SYMBOL_NS(set_crl_ondevice_size, HW_RTOS_NS);
#endif

void copyto_crl_ondevice_buf(const void *addr, size_t size)
{
	if (size > MAX_CRL_SIZE || addr == NULL)
		return;

	memcpy(crl_bundle_ondevice.buf, addr, size);
	return;
}
#ifdef CONFIG_EULEROS_CMS_CBB
EXPORT_SYMBOL_GPL(copyto_crl_ondevice_buf);
#else
EXPORT_SYMBOL_NS(copyto_crl_ondevice_buf, HW_RTOS_NS);
#endif

char *get_crl_ondevice_buf(void)
{
	return crl_bundle_ondevice.buf;
}
#ifdef CONFIG_EULEROS_CMS_CBB
EXPORT_SYMBOL_GPL(get_crl_ondevice_buf);
#else
EXPORT_SYMBOL_NS(get_crl_ondevice_buf, HW_RTOS_NS);
#endif

#ifdef CONFIG_EULEROS_CMS_CBB
static __init int crl_cert_init(void)
{
	if (system_certificate_list_size == 0) {
		pr_info("modsign: cannot find certification file\n");
		return -EBADMSG;
	}

	crl_cert_size = system_certificate_list_size;
	crl_cert = kmalloc(crl_cert_size, GFP_KERNEL);
	if (!crl_cert) {
		pr_err("modsign: malloc crl_cert failed\n");
		return -ENOMEM;
	}

	memcpy(crl_cert, system_certificate_list, crl_cert_size);
	return 0;
}
#else
static __init int crl_cert_init(void)
{
	if (system_extra_cert_used == 0 ||
		system_extra_cert_used > CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE) {
		pr_info("modsign: There is no certification file\n");
		return 0;
	}

	crl_cert_size = system_extra_cert_used;
	crl_cert = kmalloc(crl_cert_size, GFP_KERNEL);
	if (!crl_cert) {
		pr_err("modsign: Request memory for cert failed\n");
		return -ENOMEM;
	}

	memcpy(crl_cert, system_extra_cert, crl_cert_size);
	pr_info("modsign: The cert is initialized\n");
	return 0;
}
#endif
device_initcall(crl_cert_init);

#ifdef CONFIG_RTOS_EXTRA_CERTIFICATE
static __init int crl_second_cert_init(void)
{
	if (system_extra_cert_used_second == 0 ||
		system_extra_cert_used_second > CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE) {
		pr_info("modsign: There is only one cert or no cert\n");
		return 0;
	}

	crl_cert_size_second = system_extra_cert_used_second;
	crl_cert_second = kmalloc(crl_cert_size_second, GFP_KERNEL);
	if (!crl_cert_second) {
		pr_err("modsign: Request memory for second cert failed\n");
		return -ENOMEM;
	}

	memcpy(crl_cert_second, system_extra_cert_second, crl_cert_size_second);
	pr_info("modsign: The second cert is initialized\n");
	return 0;
}
device_initcall(crl_second_cert_init);
#endif
